package news

import (
	"gopkg.in/mgo.v2"
	// "fmt"
	log "github.com/sirupsen/logrus"
	"gopkg.in/mgo.v2/bson"
	"libs/db"
	
)

type Model struct {
	Mongodb *db.Mongodb
	// Redis   *db.Redis
	Table   string
}

type JsonData struct {
	Title           string `bson:"title" json:"title"`
	CreateUid       int64  `bson:"create_uid" json:"create_uid"`
	CreateUsername	string `bson:"create_username" json:"create_username"`
	CreateTime      int64  `bson:"create_time" json:"create_time"`
	UpdateTime      int64  `bson:"update_time" json:"update_time"`
	UpdateUid       int64  `bson:"update_uid" json:"update_uid"`
	UpdateUsername  string `bson:"update_username" json:"update_username"`
	Language	    string `bson:"language" json:"language"`
	Author	        string `bson:"author" json:"author"`
	Desc            string `bson:"desc" json:"desc"`
	Content         string `bson:"content" json:"content"`
	ContentHtml     string `bson:"content_html" json:"content_html"`
	Cover           string `bson:"cover" json:"cover"`
	Tags            string `bson:"tags" json:"tags"`
	Publish         int    `bson:"publish" json:"publish"`
	Source          string `bson:"source" json:"source"`
	SourceUrl       string `bson:"source_url" json:"source_url"`
	UseHtml         int    `bson:"use_html" json:"use_html"`
	Category        string `bson:"category" json:"category"`
	CategoryId      string `bson:"category_id" json:"category_id"`
	Id              bson.ObjectId `bson:"_id" json:"id"`
}


// func New(c *gin.Context) *Controller{
func NewModel(host string, port int, dbname string, args ...interface{}) *Model{
	model  := new(Model)
	model.Mongodb = db.NewMongodb(host, port, dbname, args...)
	model.Table   = "news"
	return model
}

func (this *Model) GetTable() string{
    return this.Table
}

func (this *Model) SetTable(table string){
    this.Table = table
}

func (this *Model) Insert(body JsonData, lang string) (JsonData, error) {
	var err error
	body.Id = bson.NewObjectId()
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		err = c.Insert(body)
		if err != nil {
			log.Errorf("[%s]Insert error, [Title: %s]", this.GetTable(), body.Title)
		}else{
			log.Debugf("[%s]Insert success, [Title: %s]", this.GetTable(), body.Title)
		}
    })
	return body, err
}

func (this *Model) Delete(id string, lang string) (string, error) {
	var err error
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if err = c.Remove(bson.M{"_id": bson.ObjectIdHex(id)}); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]Delete error, [id: %s]", this.GetTable(), id)
			}else{
				log.Debugf("[%s]Delete ErrNotFound, [id: %s]", this.GetTable(), id)
				err = mgo.ErrNotFound
			}
		}
    })
	return id, err
}

func (this *Model) Update(id string, body JsonData, lang string) (JsonData, error) {
	var err error
	body.Id = bson.ObjectIdHex(id)
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if err = c.Update(bson.M{"_id": bson.ObjectIdHex(id)}, body); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]Update error, [id: %s]", this.GetTable(), id)
			}else{
				log.Debugf("[%s]Update ErrNotFound, [id: %s]", this.GetTable(), id)
				err = mgo.ErrNotFound
			}
		}
    })
	return body, err
}

func (this *Model) FindAll(skip int ,limit int, lang string) ([]JsonData, error) {
	var err error
	var coin []JsonData
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if err = c.Find(nil).Sort("order").Limit(limit).Skip(skip).All(&coin); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]FindAll error, [skip: %d, limit: %d]", this.GetTable(), skip, limit)
			}else{
				log.Debugf("[%s]FindAll ErrNotFound, [skip: %d, limit: %d]", this.GetTable(), skip, limit)
				err = mgo.ErrNotFound
			}
		}
    })
	return coin, err
}

func (this *Model) FindAllM(m map[string]interface{}, skip int ,limit int, lang string) ([]JsonData, error) {
	var err error
	var coin []JsonData
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if err = c.Find(m).Sort("-create_time").Limit(limit).Skip(skip).All(&coin); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]FindAllM error, [m: %v, skip: %d, limit: %d]", this.GetTable(), m, skip, limit)
			}else{
				log.Debugf("[%s]FindAllM ErrNotFound, [m: %v, skip: %d, limit: %d]", this.GetTable(), m, skip, limit)
				err = mgo.ErrNotFound
			}
		}
    })
	return coin, err
}

func (this *Model) CountM(m map[string]interface{}, lang string) (int, error) {
	var err error
	var length int
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if length,err = c.Find(m).Count(); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]CountM error, [m: %v, language: %s]", this.GetTable(), m, lang)
			}else{
				log.Debugf("[%s]CountM ErrNotFound, [m: %v, language: %s]", this.GetTable(), m, lang)
				err = mgo.ErrNotFound
			}
		}
    })
	return length, err
}

func (this *Model) Count(lang string) (int, error) {
	var err error
	var length int
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if length,err = c.Find(nil).Count(); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]Count error, [language: %s]", this.GetTable(), lang)
			}else{
				log.Debugf("[%s]Count ErrNotFound, [language: %s]", this.GetTable(), lang)
				err = mgo.ErrNotFound
			}
		}
    })
	return length, err
}

func (this *Model) FindOne(id string, lang string) (JsonData, error) {
	var err error
	var coin JsonData
	this.Mongodb.M(lang, func(c *mgo.Collection) {
		if err = c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&coin); err != nil {
			if err.Error() != mgo.ErrNotFound.Error() {
				log.Errorf("[%s]FindOne error, [id: %s, lang: %s]", this.GetTable(), id, lang)
			}else{
				log.Debugf("[%s]FindOne ErrNotFound, [id: %s, lang: %s]", this.GetTable(), id, lang)
				err = mgo.ErrNotFound
			}
		}
    })
	return coin, err
}
